package com.uduemc.biso.node.module.node.service.impl;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

import javax.imageio.ImageIO;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.uduemc.biso.core.extities.center.Host;
import com.uduemc.biso.node.core.entities.HRepertory;
import com.uduemc.biso.node.core.property.GlobalProperties;
import com.uduemc.biso.node.core.utils.SitePathUtil;
import com.uduemc.biso.node.module.node.service.NUploadService;
import com.uduemc.biso.node.module.service.HRepertoryService;
import com.uduemc.biso.node.module.service.HostService;

@Service
public class NUploadServiceImpl implements NUploadService {

	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	HostService hostServiceImpl;

	@Autowired
	HRepertoryService hRepertoryServiceImpl;

	@Autowired
	GlobalProperties globalProperties;

	@Override
	@Transactional
	public HRepertory uploadAndInsertHRepertory(MultipartFile file, long hostId, long labelId, String basePath) {
		Host host = hostServiceImpl.findOne(hostId);
		if (host == null) {
			return null;
		}

		// 创建时间
		LocalDateTime createAt = LocalDateTime.now();

		// 通过 originalFilename 验证在当月的时间内是否存在相同的 originalFilename 名称，如果存在则对其进行递增加1处理
		String originalFilename = makeOriginalFilename(basePath, host.getRandomCode(), createAt, file.getOriginalFilename());

		// 获取文件的后缀
		String ext = originalFilename.substring(originalFilename.lastIndexOf(".") + 1, originalFilename.length()).toLowerCase();

		// 文件写入数据库中的类型
		short hRepertoryType = globalProperties.getUpload().getHRepertoryType(ext);

		// 获取当前站点以及时间的不重复的一个值
		String unidname = hRepertoryServiceImpl.getUUIDFilename(host.getId());

		// 保存文件的资源相对路径
		String filepath;
		// 文件的完整路径
		String filefullpath;
		// 这里进行判断是否是ssl证书，如果是证书则保存到另外一个目录
		if (hRepertoryType == (short) 6) {
			filefullpath = SitePathUtil.getUserNginxSSLPathByCode(basePath, host.getRandomCode()) + "/" + originalFilename;
			filepath = SitePathUtil.getSSLPath();
		} else {
			filefullpath = SitePathUtil.getUserRepertoryPathByCodeNow(basePath, host.getRandomCode(), createAt) + "/" + originalFilename;
			filepath = SitePathUtil.getRepertoryPath(createAt);
		}

		// 生成不存在的目录
		File uploadFile = new File(filefullpath);
		File parentFile = new File(uploadFile.getParent().toString());
		if (!parentFile.isDirectory()) {
			if (!parentFile.mkdirs()) {
				return null;
			}
		}

		// 生成缩放文件资源相对路径目录，不进行目录创建，预留后期功能需要
		String zoompath;
		if (hRepertoryType == (short) 6) {
			zoompath = "";
		} else {
			zoompath = filepath + "/" + unidname;
		}
		// 生成缩放文件资源相对路径目录，不进行目录创建，预留后期功能需要
		File zoomFile = new File(zoompath);
		zoompath = zoomFile.toString();

		// 最终保存至h_repertory.filepath
		filepath = filepath + "/" + originalFilename;

		// 判断是否是图片，如果是则获取图片的像素
		BufferedImage image = null;
		try (InputStream inputStream = file.getInputStream()) {
			image = ImageIO.read(inputStream);
		} catch (IOException e) {
		}
		String pixel = "";
		if (image != null) {
			pixel = image.getWidth() + "X" + image.getHeight();
		}

		HRepertory hRepertory = new HRepertory();
		hRepertory.setHostId(host.getId());
		hRepertory.setLabelId(labelId);
		hRepertory.setType(hRepertoryType);
		hRepertory.setOriginalFilename(originalFilename);
		hRepertory.setSuffix(ext);
		hRepertory.setUnidname(unidname);
		hRepertory.setFilepath(filepath);
		hRepertory.setZoompath(zoompath);
		hRepertory.setSize(file.getSize());
		hRepertory.setPixel(pixel);
		hRepertory.setIsRefuse((short) 0);
		hRepertory.setCreateAt(Date.from(createAt.atZone(ZoneId.systemDefault()).toInstant()));

		HRepertory insert = hRepertoryServiceImpl.insert(hRepertory);
		if (insert == null) {
			return null;
		}

		try {
			logger.info(filefullpath);
			file.transferTo(new File(filefullpath.toString()));
		} catch (IllegalStateException e) {
			e.printStackTrace();
			String message = "上传文件时 transferTo 操作 IllegalStateException 异常: " + e.getMessage();
			logger.error(message);
			throw new RuntimeException(message);
		} catch (IOException e) {
			e.printStackTrace();
			String message = "上传文件时 transferTo 操作 IOException 异常: " + e.getMessage();
			logger.error(message);
			throw new RuntimeException(message);
		}

		return insert;
	}

	@Override
	public String makeOriginalFilename(String basePath, String code, LocalDateTime createAt, String originalFilename) {
		// 通过判断文件是否存在
		String filepath = SitePathUtil.getUserRepertoryPathByCodeNow(basePath, code, createAt) + "/" + originalFilename;

		File file = new File(filepath);
		if (file.isFile()) {
			return makeOriginalFilename(basePath, code, createAt, makeNewOriginalFilename(originalFilename));
		}
		return originalFilename;
	}

	// 制作新的文件名
	protected static String makeNewOriginalFilename(String originalFilename) {
		int lastIndexOf = originalFilename.lastIndexOf(".");
		String start = originalFilename.substring(0, lastIndexOf);
		String end = originalFilename.substring(lastIndexOf);

		if (start.lastIndexOf("(") == -1 || start.lastIndexOf(")") == -1) {
			return start + "(1)" + end;
		} else {
			String numberStart = start.substring(0, start.lastIndexOf("("));
			String numberEnd = start.substring(start.lastIndexOf("("));
			String number = numberEnd.substring(1, numberEnd.lastIndexOf(")"));
			Long num = null;
			try {
				num = Long.valueOf(number);
			} catch (NumberFormatException e) {
			}
			if (num == null) {
				number = "(1)";
				return start + number + end;
			} else {
				number = "(" + (++num) + ")";
				return numberStart + number + end;
			}
		}
	}

}
